import { ApiMsgEnum, EntityTypeEnum, IClientInput, InputTypeEnum, IState, toFixed } from "../Common";
import { Connection } from "../Core";
import { Player } from "./Player";
import { PlayerManager } from "./PlayerManager";
import { RoomManager } from "./RoomManager";

export class Room {
    id: number;
    players: Set<Player> = new Set();
    lastTime: number; undefined;
    lastPlayerFrameIdMap: Map<number,number>=new Map();
    pendingInput: IClientInput[] = [];// 待处理的输入

    constructor(rid: number) {
        this.id = rid;
    }

    join(uid: number) {
        const player = PlayerManager.Instance.idMapPlayer.get(uid);
        if (player) {
            player.rid = this.id;// 加入房间
            this.players.add(player);
        }
    }
    leave(uid: number) {
        const player = PlayerManager.Instance.idMapPlayer.get(uid);
        if (player) {
            player.rid = undefined;// 离开房间
            this.players.delete(player);
            if (!this.players.size) {
                RoomManager.Instance.closeRoom(this.id);//  房间没人了 关闭房间
            }
        }

    }
    close() {
        this.players.clear();// 清除所有玩家
    }
    //初始化信息
    start() {
        const state: IState = {
            actor: [...this.players].map((player, index) => ({
                id: player.id,
                nickname: player.nickname,
                type: EntityTypeEnum.Actor1,
                weaponType: EntityTypeEnum.Weapon1,
                bulletType: EntityTypeEnum.Bullet2,
                hp: 100,
                position: {
                    x: -150 + 300 * Math.random(),
                    y: -150 + 300 * Math.random(),
                    z: 0
                },
                direction: {
                    x: 1,
                    y: 0,
                    z: 0
                },
            })),
            bullet: [],
            nextBulletId: 1,
        }

        for (const player of this.players) {
            player.connection.sendMsg(ApiMsgEnum.MsgGameStart, {
                state,
            })
            player.connection.listenMsg(ApiMsgEnum.MsgClientSync, this.getClientSync, this)
        }
        const timer1 = setInterval(() => {
            this.senServerMsg()
        }, 100)
        const timer2 = setInterval(() => {
            this.timePast()
        }, 16)
    }
    getClientSync(connection:Connection, { input, frameId }) {
        this.pendingInput.push(input);
        this.lastPlayerFrameIdMap.set(connection.playerId, frameId);
    }

    // 定时发送服务器消息
    senServerMsg() {
        const inputs = this.pendingInput;
        this.pendingInput = [];
        for (const player of this.players) {
            player.connection.sendMsg(ApiMsgEnum.MsgServerSync, {
                lastFrameId: this.lastPlayerFrameIdMap.get(player.id)??0,
                inputs
            })
        }
    }

    //  每帧更新
    timePast() {
        const now = process.uptime();
        const dt = now - (this.lastTime ?? now);

        this.pendingInput.push({
            type: InputTypeEnum.TimePast,
            dt:toFixed(dt),
        })
        this.lastTime=now;
    }

    sync() {
        for (const player of this.players) {
            player.connection.sendMsg(ApiMsgEnum.MsgRoom, {
                room: RoomManager.Instance.getRoomView(this),
            })
        }
    }
}